using LightCAD.MathLib;
using System;
using System.Collections;
using System.Collections.Generic;


namespace LightCAD.Three
{
    public class SpotLightHelper : Object3D
    {
        #region scope properties or methods
        //private static Vector3 _vector = new Vector3();
        private SpotLightHelperContext getContext()
        {
            return ThreeThreadContext.GetCurrThreadContext().SpotLightHelperCtx;
        }
        #endregion

        #region Properties

        public SpotLight light;
        public Color color;
        public LineSegments cone;

        #endregion

        #region constructor
        public SpotLightHelper(SpotLight light, Color color)
        {
            this.light = light;
            this.matrix = light.matrixWorld;
            this.matrixAutoUpdate = false;
            this.color = color;
            this.type = "SpotLightHelper";
            var geometry = new BufferGeometry();
            var positions = new ListEx<double> {
                    0, 0, 0, 0, 0, 1,
                    0, 0, 0, 1, 0, 1,
                    0, 0, 0, -1, 0, 1,
                    0, 0, 0, 0, 1, 1,
                    0, 0, 0, 0, -1, 1
                };
            for (int i = 0, j = 1, l = 32; i < l; i++, j++)
            {
                var p1 = (i / l) * MathEx.PI * 2;
                var p2 = (j / l) * MathEx.PI * 2;
                positions.Push(
                    Math.Cos(p1), Math.Sin(p1), 1,
                    Math.Cos(p2), Math.Sin(p2), 1
                );
            }
            geometry.setAttribute("position", new Float32BufferAttribute(positions.ToArray(), 3));
            var material = new LineBasicMaterial{ fog = false, toneMapped = false };
            this.cone = new LineSegments(geometry, material);
            this.add(this.cone);
            this.update();
        }
        #endregion

        #region methods
        public void dispose()
        {
            this.cone.geometry.dispose();
            this.cone.material.dispose();
        }
        public void update()
        {
            var _vector = getContext()._vector;
            this.light.updateWorldMatrix(true, false);
            this.light.target.updateWorldMatrix(true, false);
            var coneLength = this.light.distance > 0 ? this.light.distance : 1000;
            var coneWidth = coneLength * Math.Tan(this.light.angle);
            this.cone.scale.Set(coneWidth, coneWidth, coneLength);
            _vector.SetFromMatrixPosition(this.light.target.matrixWorld);
            this.cone.lookAt(_vector);
            if (this.color != null)
            {
                (this.cone.material as LineBasicMaterial).color.Set(this.color);
            }
            else
            {
                (this.cone.material as LineBasicMaterial).color.Copy(this.light.color);
            }
        }
        #endregion

    }
}
